/**
 * @copyright Copyright (c) 2023..
 *
 * @file    public_define.h
 * @brief   描述 共用全局变量
 * @author  HC(202206728@any3.com)
 * @version 1.0
 * @date    2023-09-27
 */
#ifndef GLOBAL_DEFINE_H
#define GLOBAL_DEFINE_H
#include <iostream>
#include <string>
#include <algorithm>
#include "json/json.h"
#include "dc_util.h"
#include "data_structure.h"
//#include "klog.h"
//#include "ca/log/log.h"
#include "klogger_helper.h"
#include "adr_diagnosis.pb.h"

using namespace std;


//===========================HTTP相关宏===================================
#define STR_PREEVN "pre-"
#define STR_DEVEVN ""

#define SRT_HTTPPRE               "http://"
#define SRT_HTTPSPRE              "https://"

// // 终端获取子系统域名
// #define SRT_URL_GETSUBSYSDOMANIN    "uds.sda.changan.com.cn/uds-apigw/uds/api/v3/get-sub-sys-domain"
// #define SRT_URL_GETSUBSYSDOMANIN    "tusystem.sda.changan.com.cn/tusystem-apigw/uds/api/v3/get-sub-sys-domain"
#define SRT_URL_GETSUBSYSDOMANIN    "uds2.sda.changan.com.cn/tusystem-apigw/uds/api/v4/get-sub-sys-domain"

// 终端获取MQTT子系统域名
// #define SRT_URL_GETMQTTDOMANIN      "uds.sda.changan.com.cn/uds-apigw/uds/api/v3/get-mqtt-domain"
#define SRT_URL_GETMQTTDOMANIN      "uds2.sda.changan.com.cn/tusystem-apigw/uds/api/v3/get-mqtt-domain"

// 终端登录子系统，获取tocken
// #define SRT_URL_LOGINGETTOCKEN      "/tu-apigw/huauth/api/v3/login"
#define SRT_URL_LOGINGETTOCKEN      "/tusystem-apigw/huauth/api/v3/login"

// 获取MQTT传输模板
#define SRT_URL_MQTTDAMQTRANS      "/tu-apigw/tu-conf/api/v3/tu/get-damq-transtemplate"

// 获取根证书下载路径
#define SRT_URL_GETCACERLINK      "/tu-apigw/tu-conf/api/v1/config/business-ca-cert"

// 获取数采配置
#define SRT_URL_GETSDRCONFIG      "/hu-apigw/sdc/api/v1/hu/dataCollectConfig/info1?"
// #define SRT_URL_GETSDRCONFIG      "/tu-apigw/sdc/api/v1/hu/config"

// 上传配置拉取结果
#define SRT_URL_RESPULLRET        "/tu-apigw/sdc/api/v1/hu/callback"

// 获取文件上传链接
#define SRT_URL_GETFILEUPLOADLINK      "/tu-apigw/filecenter/api/open/v3/cloud-disk/get-upload-link-by-path"
// 上报文件上传结果
#define SRT_URL_RESFILEUPLOADRET       "/tu-apigw/filecenter/api/open/v3/cloud-disk/upload-result"

// 获取文件Id链接
#define SRT_URL_GETFILEIDLINK    "/tu-apigw/sdc/api/v1/hu/file/url"

// 获取标定文件下载链接
#define SRT_URL_GETCALIBRATIONFILELINK    "/tu-apigw/filecenter/api/open/v3/cloud-disk/get-download-link"

// 分片文件异步合并链接
#define SRT_URL_CHUNKFILEASYNMERGELINK    "/fc-apigw/filecloud/api/open/fileup/chunk-file-merge?"

// 分片文件合并结果查询链接
#define SRT_URL_CHUNKFILEMERGERESULTLINK    "/fc-apigw/filecloud/api/open/fileup/merge-status?"


#define STR_DOMAIN_SYS    "sysDomain"
#define STR_DOMAIN_TUSYS  "tuSystemDomain"
#define STR_DOMAIN_FILE   "fileDomain"
#define STR_DOMAIN_HUAPP  "huappDomain"

#define STR_DOMAIN_DAMQ  "damqDomain"


#define STR_REQ_POST  "POST"
#define STR_REQ_GET  "GET"

//===========================HTTP相关宏===================================

typedef struct ExtEventInfo
{
    uint32_t accOdometer = 0;
    uint32_t iaccOdometer = 0;
    uint32_t ndaOdometer = 0;
    
    uint32_t totalOdometer = 0;//8.14改为车辆总里程;这里单位时100m， 传给云端时km
    uint32_t cdcTotMilg = 0;//8.14改为智驾功能里程
} ExtEventInfo;

//--------------------------------全局变量----------------------------------
namespace global_data
{
    // proto文件路径  /
    static const std::string g_proto_path = "./adr/config/datacollect/proto/";
    // 本地配置文件路径,云端获取
    static const std::string g_config_path = "./adr/config/datacollect/config.conf";
    // 要脱敏的文件配置yaml
    static const std::string g_local_conf_path = "/ds/ca_adas/local.jsonc";
    // 文件补传任务文件
    static const std::string g_file_reupload_path = "/ds/ca_adas/filereupload.jsonc";
    // 事件补传任务文件
    static const std::string g_event_reupload_path = "/ds/ca_adas/EventReupload.jsonc";
        //软硬件版本路径
    static const std::string g_hardSoftwareVersion_path = "/app/etc/version.json";
    // DDS配置路径
    // static const std::string g_can_data_dds_conf = "./adr/config/datacollect/autocoredds.xml";
    // http地址
    // static const std::string g_server_addr = "https://pre-huapp.sda.changan.com.cn/api/hu/2.0/getHost";
 
    //证书公钥
    static const std::string g_rootca_cert = "./adr/config/datacollect/rootca.cer";

    static const std::string g_httpCaFilePath = "./adr/config/datacollect/";           // 出厂根证书(从quhang那取的组版放到此目录下)
    static const std::string g_SdaCaFilePath = "/ds/ca_adas/";     // 云端获取的根证书 （上面+ 拉的增量存到此处）

    static const std::string g_rootCaCertPem = "rootca.cer";
    static const std::string g_tencentSdkCrt = "ca.crt";


    // http证书位置
    extern std::string g_http_ca_path;
    // tuid路径
    extern std::string g_tuid_path;
    //证书私钥cert
    extern std::string g_client_cert;
    //证书私钥key
    extern std::string g_client_key;
    //证书私钥key 存文件流
    extern std::string g_client_keyBuff;
    //c2大版本
    extern std::string g_C2_bigVersion;
    //保存线程池
    extern std::vector<std::thread> g_c3bThread;
    // 接口版本
    static const std::string g_http_version = "20220920111806";
    // 文件管理配置
    static const std::string g_file_manager_conf = "./adr/config/datacollect/fileInfoCfg.txt";
    // 特殊trigger事件配置
    static const std::string g_spec_trg_conf = "./adr/config/datacollect/special_trg.txt";
    // 文件存储路径
    static const std::string g_file_path = "/ds/datacollect/";
    // 文件存储路径
    static const std::string g_data_path = "/ds/ca_adas/";
    //控制器名称
    static const std::string g_controler_code = "C3BJ6M";
    //营地哨兵模式host
    static const std::string g_actsen_host = "172.16.6.50";
    //营地哨兵模式port
    static const int g_actsen_port = 5003;
    extern AdrInterface::AdrDiagnosis g_adrDiagnosisSts;

    //static int desensitizeSdkInitCount=0;
    extern int desensitizeSdkInitCount;


    //上传事件信息时是否上传脱敏后的文件信息（是：视频文件得等到停车充电进行脱敏完成后文件才能上传；否：不做脱敏，直接上传）
    extern bool g_isUploadDesensFile;
    extern int g_debugFlag;
    extern std::set<string> blackTopicSet;
    extern std::set<string> noLimitBigSet;

    //车辆vin码 gd
    extern std::string g_car_vin;
    //车tuid
    extern std::string g_car_tuid;
    //状态机运行状态
    extern uint32_t g_adc_status;
    //行泊车运行状态
    extern uint32_t g_work_status;
    //车定位经度
    extern uint32_t g_car_location_lng;
    //车定位纬度
    extern uint32_t g_car_location_lat;
    //采集配置
    extern std::string g_collect_config_buf;
    //采集fenceType类型
    extern std::string g_normal_collect__fenceType;
    //采集通用地图标签文件名
    extern std::vector<std::string> g_normal_collect__filename;
    //采集所有topic
    extern std::vector<std::string> g_topics;
    //泊车采集所有topic
    extern std::vector<std::string> g_parking_topics;
    //非车采集所有topic
    extern std::vector<std::string> g_no_parking_topics;

    extern std::vector<std::string> g_topics_mid;
    extern std::vector<std::string> g_topics_vedio;
    extern std::vector<std::string> g_topics_pic;
    
    extern std::vector<std::string> g_topics_rpc;

    extern map<int, std::string> g_topics_map;//topic与编码号映射
        //cam0~6视觉标定文件名与文件内容映射
    extern map<std::string,std::string> g_fc_calib;
    static const std::string g_calibration_fc_path = "/data/ca_adas/side_calib/";//fix:标定文件路径修改，前视，周视
    //环视标定文件名与文件内容映射
    extern map<std::string,std::string> g_sc_calib;
    static const std::string g_calibration_sc_path = "/data/ca_adas/surr_calib/";//fix:标定文件路径修改,环视
    //雷达标定文件名与文件内容映射
    extern map<std::string,std::string> g_ldr_calib;
    static const std::string g_calibration_ldr_path = "/data/ca_adas/lidar_calib/";//fix:标定文件路径修改
    //全量采集配置采集topic
    static const std::string g_parkTopc_conf = "./adr/config/datacollect/parkCollectCfg.txt";

    // 从云端拉配置的json中带的配置版本号
    extern std::string g_cloudConfigVersion;
    extern std::string g_iteration;

    // 云端获取配置文件路径
    static const std::string g_config_cloud_path = "/ds/ca_adas/config_cloud.conf"; // 所有adr相关文件（除组版的）都放到/ds/ca_adas下
    // 云端下发的众包地图配置，单独保存的位置（云端每天第一次拉取才会下发，车端保存自己维护）  
    static const std::string g_config_map_path = "/ds/ca_adas/config_map.conf";
    // ADR yaml配置  
    static const std::string g_adr_yaml_config_path = "/app/ca_adas/adr/adr.yaml";
    // ADR yaml配置备份  
    static const std::string g_adr_yaml_config_backup_path = "/app/ca_adas/adr/adr.yaml.backup";
    
    // 标定文件存储路径
    static const std::string g_calibration_root_path = "/ds/ca_adas/";
    // 标定文件解压路径
    static const std::string g_tar_calibration_file_path = "/data/ca_adas/";
    // 标定文件前缀
    static const std::string g_calibration_prefix = "ca_adas";
    // 标定文件后缀
    static const std::string g_calibration_suffix = "tar.gz";

    // 文件分片的大小
    extern uint64_t g_file_chunk_size;
    // 每个分片最大值
    extern uint32_t g_per_chunk_size;
    // 分片存储路径
    static const std::string g_split_file_path = "/ds/fileChunk/";

    // 预生产/生产环境前缀
    extern std::string g_cloudNetPrefix;
    //云端配置是否拉取成功的标志
    extern bool is_use_config_cloud;

    // 拓展信息 用于事件信息里带上
    extern ExtEventInfo g_extEvent;
}

//--------------------------------函数----------------------------------

template <typename T>
inline T JsonToValue(const Json::Value &value)
{
    if (value.isArray())
    {
        return T();
    }
    if (value.is<T>())
    {
        return value.as<T>();
    }
    return T();
}
void ModifyDiagnosisSts(uint32_t setBit, string diagnosis_info = "");

//--------------------------------宏----------------------------------
// #define Log_Info(...) LOGE(__VA_ARGS__);
// #define Log_Signal(...) LOGI(__VA_ARGS__);
// #define Log_ERROR(...) LOGE(__VA_ARGS__);
// #define Log_Topic(...) LOGE(__VA_ARGS__);
// #define Log_Mqtt(...) LOGE(__VA_ARGS__);
// #define Log_Warn(...) LOGE(__VA_ARGS__);
// #define Log_Trig(...) LOGE(__VA_ARGS__);
// #define Log_Init
#define Log_Info(...) KLOGGER_ERROR(__VA_ARGS__);
#define Log_Signal(...) KLOGGER_INFO(__VA_ARGS__);
#define Log_ERROR(...) KLOGGER_ERROR(__VA_ARGS__);
#define Log_Topic(...) KLOGGER_ERROR(__VA_ARGS__);
#define Log_Mqtt(...) KLOGGER_ERROR(__VA_ARGS__);
#define Log_Warn(...) KLOGGER_ERROR(__VA_ARGS__);
#define Log_Trig(...) KLOGGER_ERROR(__VA_ARGS__);
#define Log_Inf_MAP(...) KLOGGER_ERROR(__VA_ARGS__);

#define IN
#define OUT

#define DC_SUCC 1
#define DC_FAIL 0

// for map
#define Contain_Map(map, id) (map.find(id) != map.end())
#define NotContain_Map(map, id) (!(map.find(id) != map.end()))
#define Contain_List(list, id) (std::find(list.begin(), list.end(), id) != list.end())
#define NotContain_List(list, id) (!(std::find(list.begin(), list.end(), id) != list.end()))

#define Contain_String(sting, sub) (sting.find(sub) != std::string::npos)
#define NotContain_String(sting, sub) (!(sting.find(sub) != std::string::npos))

#define MIN(a,b) (((a)<(b))?(a):(b))

#define SecondsOneHour   60*60
#define SecondsOneDay    24*60*60
#define TimeOneHour   60*60*1000
#define TimeOneDay    24*60*60*1000


#endif // GLOBAL_DEFINE_H